package com.yingsheng.bi.hks.basic.utils;

import com.yingsheng.bi.hks.basic.consts.NameDict;
import com.yingsheng.bi.hks.basic.exception.ServiceRuntimeException;
import io.minio.*;
import io.minio.errors.ErrorResponseException;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 对象存储工具类
 *
 * @author root
 */
@Slf4j
@Component
public class OssUtils implements InitializingBean {

    private static volatile OssUtils ossUtils;

    @Resource
    private MinioClient minioClient;

    private static final List<String> IMAGE_EXTENSIONS = Arrays.asList("jpg", "jpeg", "png", "gif", "bmp", "tiff", "tif", "webp", "svg");

    @Override
    public void afterPropertiesSet() throws Exception {
        if (OssUtils.ossUtils == null) {
            synchronized (OssUtils.class) {
                if (OssUtils.ossUtils == null) {
                    OssUtils.ossUtils = this;
                }
            }
        }
    }

    public static ObjectWriteResponse putObject(byte[] content, String bucketName, String objectName) {
        return putObject(new ByteArrayInputStream(content), bucketName, objectName);
    }

    public static ObjectWriteResponse putObject(File file, String bucketName, String objectName) {
        try {
            return putObject(Files.newInputStream(file.toPath()), bucketName, objectName);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceRuntimeException(e.getMessage());
        }
    }

    public static ObjectWriteResponse putObject(InputStream in, String bucketName, String objectName) {
        check(bucketName, objectName);
        Map<String, String> headers = new HashMap<>();
        headers.put(NameDict.CACHE_CONTROL, "no-cache");
        try {
            return ossUtils.minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .stream(in, in.available(), -1)
                            .extraHeaders(headers)
                            .build());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceRuntimeException(e.getMessage());
        }
    }

    public static String getSignedUrl(String bucketName, String objectName) {
        check(bucketName, objectName);
        try {
            return ossUtils.minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket(bucketName)
                            .object(objectName)
                            .expiry(1, TimeUnit.DAYS) // 设置URL有效期为1天
                            .build());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceRuntimeException(e.getMessage());
        }
    }

    public static InputStream getObject(String bucketName, String objectName) {
        check(bucketName, objectName);
        try {
            return ossUtils.minioClient.getObject(
                    GetObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .build());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceRuntimeException(e.getMessage());
        }

    }

    /**
     * 删除一个对象
     */
    public static boolean deleteObject(String bucketName, String objectName) {
        check(bucketName, objectName);
        try {
            ossUtils.minioClient.removeObject(
                    RemoveObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .build());
            return true;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return false;
    }

    /**
     * 检查对象是否存在
     */
    public static boolean exist(String bucketName, String objectName) {
        check(bucketName, objectName);
        try {
            ossUtils.minioClient.statObject(
                    StatObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .build());
            return true;
        } catch (ErrorResponseException e) {
            if (e.response().code() == 404) {
                return false;
            }
            log.error(e.getMessage(), e);
            throw new ServiceRuntimeException(e.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceRuntimeException(e.getMessage());
        }
    }

    public static void check(String bucketName, String objectName) {
        Assert.hasText(bucketName, "bucketName.not.blank");
        Assert.hasText(objectName, "objectName.not.blank");
    }

    private static boolean isImage(String fileName) {
        if (fileName == null) return false;
        String extension = getExtension(fileName).toLowerCase();
        return IMAGE_EXTENSIONS.contains(extension);
    }

    private static String getExtension(String fileName) {
        int lastIndex = fileName.lastIndexOf('.');
        if (lastIndex != -1) {
            return fileName.substring(lastIndex + 1);
        }
        return ""; // 如果没有找到'.'，则认为没有扩展名
    }

}
